import random
from typing import List, Dict, Optional
import game.card as card
from game.character import Character
from game.skill import Skill

# 游戏常量 - 从character模块导入身份常量
from game.character import ROLE_LORD, ROLE_LOYAL, ROLE_REBEL, ROLE_TRAITOR

PHASE_START = "开始阶段"
PHASE_JUDGE = "判定阶段"
PHASE_DRAW = "摸牌阶段"
PHASE_MAIN = "出牌阶段"
PHASE_DISCARD = "弃牌阶段"
PHASE_END = "结束阶段"

class GameEngine:
    """游戏引擎类，管理整个游戏逻辑"""
    def __init__(self):
        self.characters: List[Character] = []
        self.deck: List[card.Card] = []
        self.discard_pile: List[card.Card] = []
        self.current_player_index: int = 0
        self.current_phase: str = ""
        self.game_started: bool = False
        self.winner_role: Optional[str] = None
        
        # 初始化游戏
        self._initialize_game()
    
    def _initialize_game(self):
        """初始化游戏资源"""
        # 初始化角色
        self._create_characters()
        # 初始化卡牌
        self._create_deck()
        
    def _create_characters(self):
        """创建游戏角色"""
        from game.skill import (
            GuicaiSkill, JuyiSkill, WushengSkill, 
            JiuchiSkill
        )
        
        # 曹操 - 魏国
        caocao = Character("曹操", "魏", 4)
        caocao.add_skill(GuicaiSkill())
        
        # 关羽 - 蜀国
        guanyu = Character("关羽", "蜀", 4)
        guanyu.add_skill(JuyiSkill())
        guanyu.add_skill(WushengSkill())
        
        # 孙权 - 吴国
        sunquan = Character("孙权", "吴", 4)
        
        # 司马懿 - 魏国
        simayi = Character("司马懿", "魏", 3)
        simayi.add_skill(GuicaiSkill())
        
        # 曹植 - 魏国
        caozhi = Character("曹植", "魏", 3)
        caozhi.add_skill(JiuchiSkill())
        
        # 刘备 - 蜀国
        liubei = Character("刘备", "蜀", 4)
        
        # 张飞 - 蜀国
        zhangfei = Character("张飞", "蜀", 4)
        
        # 诸葛亮 - 蜀国
        zhugeliang = Character("诸葛亮", "蜀", 3)
        
        # 周瑜 - 吴国
        zhouyu = Character("周瑜", "吴", 3)
        
        # 吕蒙 - 吴国
        lvming = Character("吕蒙", "吴", 4)
        
        self.characters = [caocao, guanyu, sunquan, simayi, caozhi, liubei, zhangfei, zhugeliang, zhouyu, lvming]
        
        # 设置第一个角色为人类玩家
        if self.characters:
            self.characters[0].is_human = True
        
    def _create_deck(self):
        """创建卡牌牌堆"""
        # 花色和点数
        suits = ["红桃", "方片", "梅花", "黑桃"]
        numbers = list(range(1, 14))  # A到K
        
        card_id = 0
        
        # 创建基础牌
        # 杀牌 - 红色杀
        for suit in ["红桃", "方片"]:
            for number in numbers:
                # 限制杀的数量
                if number > 10 and len([c for c in self.deck if c.name == "杀"]) >= 24:
                    continue
                self.deck.append(card.AttackCard(card_id, suit, number))
                card_id += 1
        
        # 黑色杀
        for suit in ["梅花", "黑桃"]:
            for number in numbers:
                # 限制杀的数量
                if len([c for c in self.deck if c.name == "杀"]) >= 30:
                    continue
                self.deck.append(card.AttackCard(card_id, suit, number))
                card_id += 1
        
        # 闪牌 - 主要是红色
        for suit in ["红桃", "方片"]:
            for number in numbers:
                if len([c for c in self.deck if c.name == "闪"]) >= 15:
                    break
                self.deck.append(card.DefendCard(card_id, suit, number))
                card_id += 1
        
        # 桃牌 - 主要是红桃
        for number in numbers:
            if len([c for c in self.deck if c.name == "桃"]) >= 8:
                break
            self.deck.append(card.HealCard(card_id, "红桃", number))
            card_id += 1
        
        # 酒牌 - 主要是黑色
        for suit in ["梅花", "黑桃"]:
            for i in range(2):  # 每色2张
                if len([c for c in self.deck if c.name == "酒"]) >= 5:
                    break
                self.deck.append(card.NeutralizeCard(card_id, suit, numbers[i]))
                card_id += 1
        
        # 创建装备牌
        # 武器
        weapons = [card.WEAPON_FAN, card.WEAPON_SPEAR, card.WEAPON_SWORD, card.WEAPON_BOW, card.WEAPON_AXE]
        weapon_suits = ["红桃", "方片", "梅花", "黑桃", "红桃"]
        weapon_numbers = [1, 3, 5, 7, 9]
        for i, weapon_info in enumerate(weapons):
            self.deck.append(card.WeaponCard(card_id, weapon_info, weapon_suits[i], weapon_numbers[i]))
            card_id += 1
        
        # 防具
        armors = [card.ARMOR_LEATHER, card.ARMOR_MAIL, card.ARMOR_PLASTE]
        armor_suits = ["方片", "梅花", "黑桃"]
        armor_numbers = [2, 4, 6]
        for i, armor_info in enumerate(armors):
            self.deck.append(card.ArmorCard(card_id, armor_info, armor_suits[i], armor_numbers[i]))
            card_id += 1
        
        # 坐骑
        # 进攻马
        self.deck.append(card.MountCard(card_id, card.MOUNT_ATTACK_HORSE, card.EQUIP_MOUNT_ATTACK, "红桃", 5))
        card_id += 1
        # 防御马
        self.deck.append(card.MountCard(card_id, card.MOUNT_DEFEND_HORSE, card.EQUIP_MOUNT_DEFEND, "黑桃", 5))
        card_id += 1
        
        # 洗牌
        random.shuffle(self.deck)
    
    def start_game(self):
        """开始游戏"""
        self.game_started = True
        # 分配角色和身份
        self._assign_roles()
        # 初始化玩家手牌
        self._deal_initial_cards()
        # 设置主公
        self._set_lord()
        # 开始第一个回合
        self.current_player_index = 0
        self.current_phase = PHASE_START
    
    def _assign_roles(self):
        """分配角色身份"""
        num_players = len(self.characters)
        roles = [ROLE_LORD]
        
        if num_players == 5:
            roles.extend([ROLE_LOYAL, ROLE_REBEL, ROLE_REBEL, ROLE_TRAITOR])
        elif num_players == 6:
            roles.extend([ROLE_LOYAL, ROLE_LOYAL, ROLE_REBEL, ROLE_REBEL, ROLE_REBEL])
        elif num_players == 7:
            roles.extend([ROLE_LOYAL, ROLE_LOYAL, ROLE_REBEL, ROLE_REBEL, ROLE_REBEL, ROLE_TRAITOR])
        elif num_players == 8:
            roles.extend([ROLE_LOYAL, ROLE_LOYAL, ROLE_REBEL, ROLE_REBEL, ROLE_REBEL, ROLE_REBEL, ROLE_TRAITOR])
        else:  # 4人局
            roles.extend([ROLE_LOYAL, ROLE_REBEL, ROLE_TRAITOR])
        
        random.shuffle(roles)
        for i, char in enumerate(self.characters):
            char.role = roles[i]
    
    def _set_lord(self):
        """设置主公并增加体力"""
        for char in self.characters:
            if char.role == ROLE_LORD:
                char.is_lord = True
                char.max_health += 1
                char.health = char.max_health
                break
    
    def _deal_initial_cards(self):
        """发初始手牌"""
        for char in self.characters:
            # 根据体力值发牌
            cards_to_deal = char.max_health
            for _ in range(cards_to_deal):
                if self.deck:
                    card = self.deck.pop()
                    char.hand.append(card)
    
    def update(self):
        """更新游戏状态"""
        if not self.game_started or self.is_game_over():
            return
        
        current_player = self.characters[self.current_player_index]
        
        # 跳过已死亡的角色
        if current_player.dead:
            self.next_turn()
            return
        
        # 处理游戏阶段
        if self.current_phase == PHASE_START:
            # 开始阶段逻辑
            self._handle_start_phase(current_player)
        elif self.current_phase == PHASE_JUDGE:
            # 判定阶段逻辑
            self._handle_judge_phase(current_player)
        elif self.current_phase == PHASE_DRAW:
            # 摸牌阶段逻辑
            self._handle_draw_phase(current_player)
        elif self.current_phase == PHASE_MAIN:
            # 出牌阶段逻辑
            self._handle_main_phase(current_player)
        elif self.current_phase == PHASE_DISCARD:
            # 弃牌阶段逻辑
            self._handle_discard_phase(current_player)
        elif self.current_phase == PHASE_END:
            # 结束阶段逻辑
            self._handle_end_phase(current_player)
        else:
            # 异常情况下重置阶段
            print(f"警告：未知的游戏阶段 '{self.current_phase}'，重置为开始阶段")
            self.current_phase = PHASE_START
    
    def _handle_start_phase(self, player: Character):
        """处理开始阶段"""
        # TODO: 触发开始阶段技能
        self.current_phase = PHASE_JUDGE
    
    def _handle_judge_phase(self, player: Character):
        """处理判定阶段"""
        # TODO: 处理延时锦囊判定
        self.current_phase = PHASE_DRAW
    
    def _handle_draw_phase(self, player: Character):
        """处理摸牌阶段"""
        # 摸2张牌
        for _ in range(2):
            if self.deck:
                card = self.deck.pop()
                player.hand.append(card)
        self.current_phase = PHASE_MAIN
    
    def _handle_main_phase(self, player: Character):
        """处理出牌阶段"""
        # 如果是AI玩家，则自动出牌
        if not player.is_human:
            # 简单的AI出牌逻辑
            # 1. 先使用桃来恢复体力
            for card in player.hand[:]:
                if card.name == "桃" and player.health < player.max_health:
                    self._use_heal_card(player, card)
                    break
            
            # 2. 尝试使用杀攻击敌人
            for card in player.hand[:]:
                if card.name == "杀":
                    # 寻找合适的目标（非己方角色）
                    target = self._find_attack_target(player)
                    if target:
                        # 使用杀攻击目标
                        self._use_attack_card(player, target, card)
                        # 每个回合只能出一次杀（除非有特殊技能）
                        break
            
            # 3. 尝试使用装备牌
            for card in player.hand[:]:
                if card.card_type == "equipment":
                    # 装备卡牌
                    self._equip_card(player, card)
                    break
            
            # 4. 如果以上都做不了，直接结束出牌阶段
            self.current_phase = PHASE_DISCARD
        else:
            # 人类玩家的出牌阶段，依赖于UI交互结束阶段
            # 这里不做任何操作，等待UI触发阶段转换
            # 可以添加一个回合计时器，避免游戏卡在这里
            if not hasattr(player, 'phase_timer'):
                player.phase_timer = 0
            else:
                player.phase_timer += 1
                # 如果超过一定帧数没有操作（例如30秒），自动结束出牌阶段
                # 防止游戏卡死
                if player.phase_timer > 1800:  # 假设60FPS，1800=30秒
                    print(f"[{player.name}] 出牌阶段超时，自动结束回合")
                    self.current_phase = PHASE_DISCARD
                    player.phase_timer = 0
        
    def _use_heal_card(self, player: Character, card):
        """使用桃牌恢复体力"""
        # 移除手牌
        player.hand.remove(card)
        # 添加到弃牌堆
        self.discard_pile.append(card)
        # 恢复体力
        player.health = min(player.health + 1, player.max_health)
        print(f"{player.name} 使用了桃，恢复了1点体力！")
    
    def _use_attack_card(self, player: Character, target: Character, card):
        """使用杀攻击目标"""
        # 检查目标是否在攻击范围内
        if not self._is_in_attack_range(player, target):
            return False
        
        # 移除手牌
        player.hand.remove(card)
        # 添加到弃牌堆
        self.discard_pile.append(card)
        
        # 造成伤害
        target.take_damage(1)
        print(f"{player.name} 使用杀攻击了 {target.name}！")
        
        # 检查目标是否死亡
        if target.dead:
            print(f"{target.name} 被击败了！")
        
        return True
    
    def _equip_card(self, player: Character, card):
        """装备卡牌"""
        # 移除手牌
        player.hand.remove(card)
        
        # 检查是否已装备同类型的卡牌
        equip_type = card.subtype
        existing_equip = None
        
        # 查找并移除同类型的装备
        for equip in player.equipment_area[:]:
            if equip.subtype == equip_type:
                existing_equip = equip
                player.equipment_area.remove(equip)
                self.discard_pile.append(equip)
                break
        
        # 装备新卡牌
        player.equipment_area.append(card)
        
        print(f"{player.name} 装备了 {card.name}！")
        if existing_equip:
            print(f"{player.name} 替换了装备：{existing_equip.name} -> {card.name}")
    
    def _find_attack_target(self, player: Character):
        """寻找合适的攻击目标"""
        enemies = []
        for char in self.characters:
            # 不能攻击自己，且目标必须存活
            if char != player and not char.dead:
                # 简单的敌对关系判断：主公和忠臣是同一阵营，其他为敌对阵营
                if player.role == ROLE_LORD and char.role != ROLE_LOYAL:
                    enemies.append(char)
                elif player.role == ROLE_LOYAL and char.role not in [ROLE_LORD, ROLE_LOYAL]:
                    enemies.append(char)
                elif player.role == ROLE_REBEL and char.role == ROLE_LORD:
                    enemies.append(char)
                elif player.role == ROLE_TRAITOR and char.role != ROLE_TRAITOR:
                    enemies.append(char)
        
        # 优先选择在攻击范围内的敌人
        for enemy in enemies:
            if self._is_in_attack_range(player, enemy):
                return enemy
        
        return None
    
    def _is_in_attack_range(self, player: Character, target: Character):
        """检查目标是否在攻击范围内"""
        # 计算基础距离
        # 计算实际距离（考虑座位顺序）
        players_count = len(self.characters)
        player_index = self.characters.index(player)
        target_index = self.characters.index(target)
        
        # 计算顺时针和逆时针距离，取较小值
        clockwise = (target_index - player_index) % players_count
        counter_clockwise = (player_index - target_index) % players_count
        actual_distance = min(clockwise, counter_clockwise)
        
        # 考虑装备的武器和坐骑
        attack_range = 1  # 基础攻击距离
        
        # 检查武器
        for equip in player.equipment_area:
            if equip.subtype == "weapon" and hasattr(equip, 'range'):
                attack_range = equip.range
                break
        
        # 检查进攻马
        for equip in player.equipment_area:
            if equip.subtype == "mount" and hasattr(equip, 'attack_bonus'):
                attack_range += equip.attack_bonus
                break
        
        # 检查目标的防御马
        for equip in target.equipment_area:
            if equip.subtype == "mount" and hasattr(equip, 'defense_bonus'):
                actual_distance += equip.defense_bonus
                break
        
        return actual_distance <= attack_range
    
    def _handle_discard_phase(self, player: Character):
        """处理弃牌阶段"""
        # 弃置多余的手牌
        while len(player.hand) > player.health:
            # 如果是AI玩家，自动选择弃牌
            if not player.is_human:
                # 简单AI逻辑：优先弃装备牌和锦囊牌
                card_to_discard = None
                for card in player.hand:
                    if card.card_type != "basic":
                        card_to_discard = card
                        break
                if not card_to_discard and player.hand:
                    card_to_discard = player.hand[0]
                
                if card_to_discard:
                    player.hand.remove(card_to_discard)
                    self.discard_pile.append(card_to_discard)
        
        self.current_phase = PHASE_END
    
    def _handle_end_phase(self, player: Character):
        """处理结束阶段"""
        # 重置回合状态
        if hasattr(player, 'phase_timer'):
            player.phase_timer = 0
        player.end_turn_reset()
        # TODO: 触发结束阶段技能
        self.next_turn()
    
    def next_turn(self):
        """进入下一回合"""
        self.current_player_index = (self.current_player_index + 1) % len(self.characters)
        self.current_phase = PHASE_START
    
    def is_game_over(self) -> bool:
        """检查游戏是否结束"""
        # 检查主公是否死亡
        lord_alive = any(char.role == ROLE_LORD and not char.dead for char in self.characters)
        if not lord_alive:
            # 检查反贼是否全部存活
            rebels_alive = any(char.role == ROLE_REBEL and not char.dead for char in self.characters)
            traitors_alive = any(char.role == ROLE_TRAITOR and not char.dead for char in self.characters)
            
            if rebels_alive:
                self.winner_role = ROLE_REBEL
            elif traitors_alive:
                self.winner_role = ROLE_TRAITOR
            return True
        
        # 检查反贼和内奸是否全部死亡
        non_loyal_alive = any(char.role in [ROLE_REBEL, ROLE_TRAITOR] and not char.dead for char in self.characters)
        if not non_loyal_alive:
            self.winner_role = ROLE_LOYAL
            return True
        
        return False
    
    def add_character(self, character: Character):
        """添加角色到游戏"""
        if not self.game_started:
            self.characters.append(character)
    
    def get_winner_role(self) -> Optional[str]:
        """获取获胜方角色"""
        return self.winner_role
    
    def get_current_player(self) -> Optional[Character]:
        """获取当前玩家"""
        if self.characters and 0 <= self.current_player_index < len(self.characters):
            return self.characters[self.current_player_index]
        return None
    
    def get_characters(self) -> List[Character]:
        """获取所有角色"""
        return self.characters
    
    def get_current_phase(self) -> str:
        """获取当前游戏阶段"""
        return self.current_phase